home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
lang
/
fpcsrc.lha
/
fpc
/
compiler
/
pmodules.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-09-24
|
44KB
|
1,189 lines
{
$Id: pmodules.pas,v 1.2.2.6 1998/09/14 18:58:09 carl Exp $
Copyright (c) 1998 by Florian Klaempfl
Handles the parsing and loading of the modules (ppufiles)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit pmodules;
interface
uses
dos,strings,
cobjects,globals,scanner,symtable,aasm,tree,pass_1,
types,hcodegen,files,verbose,systems,link,assemble
{$ifdef GDB}
,gdb
{$endif GDB}
{ parser specific stuff }
,pbase,pdecl,pstatmnt,psub
{ processor specific stuff }
{$ifdef i386}
,i386
,cgai386
,tgeni386
,cgi386
,aopt386
{$endif}
{$ifdef m68k}
,m68k
,cga68k
,tgen68k
,cg68k
{$endif}
;
function loadunit(const s : string;compile_system, in_uses : boolean) : pmodule;
procedure proc_unit;
procedure proc_program(islibrary : boolean);
implementation
uses
parser;
{$I innr.inc}
procedure insertinternsyms(p : psymtable);
begin
p^.insert(new(psyssym,init('CONCAT',in_concat_x)));
p^.insert(new(psyssym,init('WRITE',in_write_x)));
p^.insert(new(psyssym,init('WRITELN',in_writeln_x)));
p^.insert(new(psyssym,init('ASSIGNED',in_assigned_x)));
p^.insert(new(psyssym,init('READ',in_read_x)));
p^.insert(new(psyssym,init('READLN',in_readln_x)));
p^.insert(new(psyssym,init('OFS',in_ofs_x)));
p^.insert(new(psyssym,init('SIZEOF',in_sizeof_x)));
p^.insert(new(psyssym,init('TYPEOF',in_typeof_x)));
p^.insert(new(psyssym,init('LOW',in_low_x)));
p^.insert(new(psyssym,init('HIGH',in_high_x)));
p^.insert(new(psyssym,init('SEG',in_seg_x)));
p^.insert(new(psyssym,init('ORD',in_ord_x)));
p^.insert(new(psyssym,init('PRED',in_pred_x)));
p^.insert(new(psyssym,init('SUCC',in_succ_x)));
{ for testing purpose }
p^.insert(new(psyssym,init('DECI',in_dec_x)));
p^.insert(new(psyssym,init('INCI',in_inc_x)));
p^.insert(new(psyssym,init('STR',in_str_x_string)));
end;
procedure load_ppu(oldhp,hp : pmodule;compile_system : boolean);
var
loaded_unit : pmodule;
b : byte;
checksum,
count,
nextmapentry : longint;
hs : string;
w1,w2 : word;
begin
{ init the map }
new(hp^.map);
nextmapentry:=1;
{ load the used units from interface }
hp^.ppufile^.read_data(b,1,count);
while (b=ibloadunit) do
begin
{ read unit name }
hp^.ppufile^.read_data(hs[0],1,count);
hp^.ppufile^.read_data(hs[1],byte(hs[0]),count);
hp^.ppufile^.read_data(checksum,4,count);
{$ifdef BIG_ENDIAN}
w1:=checksum and $ffff;
w2:=checksum shr 16;
checksum:=swap(w2)+(longint(swap(w1)) shl 16);
{$endif}
loaded_unit:=loadunit(hs,false,false);
if hp^.compiled then
exit;
{ if the crc of a used unit is the same as }
{ written to the PPU file, we needn't to }
{ recompile the current unit }
if (loaded_unit^.crc<>checksum) or
(do_build and loaded_unit^.sources_avail) then
begin
{ we have to compile the current unit }
{ remove stuff which isn't needed }
{ forget the map }
dispose(hp^.map);
hp^.map:=nil;
hp^.ppufile^.close;
dispose(hp^.ppufile,done);
hp^.ppufile:=nil;
if assigned(oldhp^.current_inputfile) then
oldhp^.current_inputfile^.tempclose;
compile(hp^.mainsource^,compile_system);
if (not oldhp^.compiled) and assigned(oldhp^.current_inputfile) then
oldhp^.current_inputfile^.tempreopen;
exit;
end;
{ setup the map entry for deref }
hp^.map^[nextmapentry]:=loaded_unit^.symtable;
inc(nextmapentry);
if nextmapentry>maxunits then
Message(unit_f_too_much_units);
{ read until ibend }
hp^.ppufile^.read_data(b,1,count);
end;
{ ok, now load the unit }
hp^.symtable:=new(punitsymtable,load(hp^.unitname^));
{ if this is the system unit insert the intern }
{ symbols }
if compile_system then
insertinternsyms(psymtable(hp^.symtable));
{ now only read the implementation part }
hp^.in_implementation:=true;
{ load the used units from implementation }
hp^.ppufile^.read_data(b,1,count);
while (b<>ibend) and (b=ibloadunit) do
begin
{ read unit name }
hp^.ppufile^.read_data(hs[0],1,count);
hp^.ppufile^.read_data(hs[1],byte(hs[0]),count);
hp^.ppufile^.read_data(checksum,4,count);
loaded_unit:=loadunit(hs,false,false);
if hp^.compiled then exit;
{ if the crc of a used unit is the same as }
{ written to the PPU file, we needn't to }
{ recompile the current unit }
{ but for the implementation part }
{ the written crc is false, because }
{ not defined when writing the ppufile !! }
if {(loaded_unit^.crc<>checksum) or}
(do_build and loaded_unit^.sources_avail) then
begin
{ we have to compile the current unit }
{ remove stuff which isn't needed }
{ forget the map }
dispose(hp^.map);
hp^.map:=nil;
hp^.ppufile^.close;
dispose(hp^.ppufile,done);
hp^.ppufile:=nil;
if not(hp^.sources_avail) then
Message1(unit_f_cant_compile_unit,hp^.unitname^)
else
begin
oldhp^.current_inputfile^.tempclose;
compile(hp^.mainsource^,compile_system);
oldhp^.current_inputfile^.tempclose;
end;
exit;
end;
{ read until ibend }
hp^.ppufile^.read_data(b,1,count);
end;
hp^.ppufile^.close;
dispose(hp^.map);
hp^.map:=nil;
end;
function loadunit(const s : string;compile_system, in_uses : boolean) : pmodule;
var
st : punitsymtable;
old_current_module,hp,nextmodule : pmodule;
pu : pused_unit;
a : pasmfile;
hs : pstring;
i : longint;
begin
old_current_module:=current_module;
{ be sure not to mix lines from different files }
{ update_line; }
{ unit not found }
st:=nil;
{ search all loaded units }
hp:=pmodule(loaded_units.first);
while assigned(hp) do
begin
if hp^.unitname^=s then
begin
{ the unit is alr